<script setup lang="ts">
import { ref } from "vue";
import Sortable from "sortablejs";
import { message } from "@/utils/message";
import { formRules } from "./utils/rule";
import { FormProps } from "./utils/types";
import type { UploadFile } from "element-plus";

import Add from "@iconify-icons/ep/plus";
import Eye from "@iconify-icons/ri/eye-line";
import Delete from "@iconify-icons/ri/delete-bin-7-line";

const props = withDefaults(defineProps<FormProps>(), {
  formInline: () => ({
    id: 0,
    category: "",
    fileList: [],
    url: "",
    imagetype: ""
  })
});

const imagetype = ["jpg", "png", "PNG", "JPG", "jpeg", "JPEG", "gif", "GIF"];

const fileList = ref([]);
const curOpenImgIndex = ref(0);
const ruleFormRef = ref();
const newFormInline = ref(props.formInline);
const dialogVisible = ref(false);
const { VITE_UPLOAD_URL } = import.meta.env;

/** 上传文件前校验 */
const onBefore = file => {
  // if (!["image/jpeg", "image/png", "image/gif"].includes(file.type)) {
  //   message("只能上传图片");
  //   return false;
  // }
  // const isExceed = file.size / 1024 / 1024 > 2;
  // if (isExceed) {
  //   message(`单个图片大小不能超过2MB`);
  //   return false;
  // }
};

/** 超出最大上传数时触发 */
const onExceed = () => {
  message("最多上传1张图片，请先删除在上传");
};

/** 移除上传的文件 */
const handleRemove = (file: UploadFile) => {
  fileList.value.splice(fileList.value.indexOf(file), 1);
};

/** 大图预览 */
const handlePictureCardPreview = (file: UploadFile) => {
  curOpenImgIndex.value = fileList.value.findIndex(img => img.uid === file.uid);
  dialogVisible.value = true;
};

const getUploadItem = () => document.querySelectorAll("#pure-upload-item");

/** 缩略图拖拽排序 */
const imgDrop = uid => {
  const CLASSNAME = "el-upload-list";
  const _curIndex = fileList.value.findIndex(img => img.uid === uid);
  getUploadItem()?.[_curIndex]?.classList?.add(`${CLASSNAME}__item-actions`);
  const wrapper: HTMLElement = document.querySelector(`.${CLASSNAME}`);
  Sortable.create(wrapper, {
    handle: `.${CLASSNAME}__item`,
    onEnd: ({ newIndex, oldIndex }) => {
      const oldFile = fileList.value[oldIndex];
      fileList.value.splice(oldIndex, 1);
      fileList.value.splice(newIndex, 0, oldFile);
      getUploadItem().forEach(ele => {
        ele.classList.remove(`${CLASSNAME}__item-actions`);
      });
    }
  });
};

function getRef() {
  return ruleFormRef.value;
}

defineExpose({ getRef });
</script>

<template>
  <el-form
    ref="ruleFormRef"
    :model="newFormInline"
    :rules="formRules"
    label-width="82px"
  >
    <!-- 如果 newFormInline.id ==0 不显示文件分类 -->
    <el-form-item
      v-if="newFormInline.id !== 0"
      label="文件分类"
      prop="category"
    >
      <el-input
        v-model="newFormInline.category"
        clearable
        placeholder="请输入文件分类"
      />
    </el-form-item>
    <!-- 如果 newFormInline.id  ！= 0 时 根据mimetype格式判断，获取url，单纯显示图片或者其他 -->
    <el-form-item v-if="newFormInline.id !== 0" label="文件" prop="file">
      <el-image
        v-if="imagetype.includes(newFormInline.imagetype)"
        style="width: 100px; height: auto"
        :src="newFormInline.url"
        fit="cover"
      />
      <el-link
        v-else
        :href="newFormInline.url"
        target="_blank"
        type="primary"
        underline
        :download="newFormInline.url"
        >{{ newFormInline.url }}</el-link
      >
    </el-form-item>

    <el-form-item v-if="newFormInline.id === 0" label="文件" prop="file">
      <el-upload
        v-model:file-list="fileList"
        drag
        multiple
        class="pure-upload"
        list-type="picture-card"
        accept="*"
        :action="VITE_UPLOAD_URL"
        :limit="1"
        :on-exceed="onExceed"
        :before-upload="onBefore"
      >
        <IconifyIconOffline :icon="Add" class="m-auto mt-4" width="30" />
        <template #file="{ file }">
          <div
            v-if="file.status == 'ready' || file.status == 'uploading'"
            class="mt-[35%] m-auto"
          >
            <p class="font-medium">文件上传中</p>
            <el-progress
              class="mt-2"
              :stroke-width="2"
              :text-inside="true"
              :show-text="false"
              :percentage="file.percentage"
            />
          </div>
          <div v-else @mouseenter.stop="imgDrop(file.uid)">
            <img
              class="el-upload-list__item-thumbnail select-none"
              :src="file.url"
            />
            <span
              id="pure-upload-item"
              :class="[
                'el-upload-list__item-actions',
                fileList.length > 1 && '!cursor-move'
              ]"
            >
              <span
                title="查看"
                class="hover:text-primary"
                @click="handlePictureCardPreview(file)"
              >
                <IconifyIconOffline
                  :icon="Eye"
                  class="hover:scale-125 duration-100"
                />
              </span>
              <span
                class="el-upload-list__item-delete"
                @click="handleRemove(file)"
              >
                <span title="移除" class="hover:text-[var(--el-color-danger)]">
                  <IconifyIconOffline
                    :icon="Delete"
                    class="hover:scale-125 duration-100"
                  />
                </span>
              </span>
            </span>
          </div>
        </template>
      </el-upload>
    </el-form-item>
  </el-form>
</template>

<style lang="scss" scoped>
:deep(.card-header) {
  display: flex;

  .header-right {
    display: flex;
    flex: auto;
    align-items: center;
    justify-content: flex-end;
    font-size: 14px;
  }
}

:deep(.pure-upload) {
  .el-upload-dragger {
    background-color: transparent;
    border: none;
  }
}

.img-name {
  position: absolute;
  bottom: 80px;
  left: 50%;
  z-index: 4000;
  padding: 5px 23px;
  background-color: var(--el-text-color-regular);
  border-radius: 22px;
  transform: translateX(-50%);

  /** 将下面的 left: 50%; bottom: 80px; transform: translateX(-50%); 注释掉
   *  解开下面 left: 40px; top: 40px; 注释，体验不一样的感觉。啊？还是差强人意，自己调整位置吧🥹
   */
  // left: 40px;
  // top: 40px;
}
</style>
